
package threadlogging.jdk;

import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import java.util.logging.*;

import threadlogging.common.CyclicBuffer;

/**
 * 
 *  NOTE:  this class is still under development
 *  
 *  ThreadTrace for java.util.logging.LogRecord objects
 * 
 * @author Sean C. Sullivan
 *
 */
public class ThreadTrace
{
	public static final Integer DEFAULT_BUFFER_SIZE = new Integer(150);
	private static ThreadLocal<HttpServletRequest> httpRequestTL = new ThreadLocal<HttpServletRequest>();
	private static ThreadLocal<CyclicBuffer<LogRecord>> cyclicBufferTL = new ThreadLocal<CyclicBuffer<LogRecord>>();
	private static ThreadLocal<LogRecord> lastErrorTL = new ThreadLocal<LogRecord>();
	private static ThreadLocal<Integer> cyclicBufferSizeTL = new ThreadLocal<Integer>();
	private static ThreadLocal<Boolean> enabledTL = new ThreadLocal<Boolean>();
	
	public static void setEnabled(boolean b)
	{
		enabledTL.set(Boolean.valueOf(b));
	}
	
	public static boolean isEnabled()
	{
		Boolean b = enabledTL.get();
		if (b == null)
		{
			return false;
		}
		else
		{
			return b.booleanValue();
		}
	}
	
	public static void setCyclicBufferSize(int size)
	{
		cyclicBufferSizeTL.set(new Integer(size));
		
		getCyclicBuffer().resize(size);
		
	}
	
	public static Integer getCyclicBufferSize()
	{
		Integer size = cyclicBufferSizeTL.get();
		if (size == null)
		{
			return DEFAULT_BUFFER_SIZE;
		}
		else
		{
			return size;
		}
	}
	
	public static void clear()
	{
		httpRequestTL.remove();
		cyclicBufferTL.remove();
		lastErrorTL.remove();

		// NOTE:   we do not call cyclicBufferSizeTL.remove(). This is intentional. 
		
		// NOTE:   we do not call enabledTL.remove().  This is intentional.
	}

	public static void setHttpRequest(HttpServletRequest req)
	{
		httpRequestTL.set(req);
	}
	
	public static Iterator<LogRecord> iterator()
	{
		return getCyclicBuffer().iterator();  
	}
	
	public static Iterator<LogRecord> reverseIterator()
	{
		return getCyclicBuffer().reverseIterator(); 
	}
	
	public static HttpServletRequest getHttpServletRequest()
	{
		return httpRequestTL.get();
	}
	
	public static boolean hasError()
	{
		return (getLastError() != null);
	}
	
	public static CyclicBuffer<LogRecord> getCyclicBuffer()
	{
		CyclicBuffer<LogRecord> cb = cyclicBufferTL.get();
		if (cb == null)
		{
			cb = new CyclicBuffer<LogRecord>(getCyclicBufferSize().intValue());
			cyclicBufferTL.set(cb);
		}
		return cb;
	}
	
	public static void add(LogRecord record)
	{
		if ( ! isEnabled() )
		{
			return;
		}
		
		getCyclicBuffer().add(record);
		
		if (record.getLevel().intValue() >= java.util.logging.Level.WARNING.intValue())
		{
			setLastError(record);
		}
	}

	static private void setLastError(LogRecord e)
	{
		lastErrorTL.set(e);
	}
	
	static private LogRecord getLastError()
	{
		return (LogRecord) lastErrorTL.get();
	}
}
